from flask import jsonify, g
from flask_restful import marshal
from sqlalchemy import and_, or_, not_

from app.api.wxapp.fields import user_fields, category_fields, rank_fields, sponsor_records_fields, \
    doll_records_fields, lastest_order_fields
from app.exception import APIException, SERVER_ERROR, USER_NOT_EXISTS, DOLL_NOT_ENOUGH, DATABASE_ERROR
from app.extensions import wx, auth, db
from app.api.wxapp.parsers import wxapp_login_args, rank_type_args, get_param_parser, pagination_parser, sponsor_args
from app.models import UserLogin, User, Category, UserSponsorRecord, UserRecord, Order, RemoteArea, SecondaryCategory


# 登录
def login():
    args = wxapp_login_args.parse_args()
    res_data = wx.jscode2session(args.get('code'))
    if res_data.get("errcode"):
        raise APIException(SERVER_ERROR)
    user_info = wx.decrypt(res_data.get('session_key'), args.get('encryptedData'), args.get('iv'))

    user_info.pop('watermark')
    user_info.pop('language')
    openid = user_info.pop('openId')
    user_login = UserLogin.query.filter(and_(UserLogin.identity_type == 'weixin', UserLogin.identifier == openid)).first()
    # user = None
    if user_login:
        user = User.query.get(user_login.user_id)
        if user.nickname != user_info.get("nickName"):
            user.nickname = user_info.get("nickName")
            user.update(True, )
        if user.avatar != user_info.get("avatarUrl"):
            user.avatar = user_info.get("avatarUrl")
            user.update(True, )

    else:
        row = {
            'uid': 0,
            'branch_id': 0,
            'status': 1,
            'doll': 0,
            'nickname': user_info.get("nickName"),
            'avatar': user_info.get('avatarUrl'),
            'gender': user_info.get('gender'),
            'city': user_info.get('city'),
            'province': user_info.get('province'),
            'country': user_info.get('country')
        }
        user = User.create(False, **row)
        user.uid = str(user.id)
        user.update(False,)
        row1 = {
            'user_id': user.id,
            'identity_type': 'weixin',
            'identifier': openid,
            'credential': '',
            'enabled': 1
        }
        UserLogin.create(False, **row1)
        try:
            db.session.commit()
        except Exception as e:
            db.session.rollback()
            raise APIException(DATABASE_ERROR)
    return jsonify({
        'code': 0,
        'message': '',
        'data': {
            'token': user.generate_auth_token(),
            'userInfo': marshal(user, user_fields)
        }
    }), 200


@auth.login_required
def get_me():
    return jsonify({
        'code': 0,
        'data': marshal(g.user, user_fields)
    }), 200


# @auth.login_required
def get_category_list():
    """ 获取主分类列表 """
    category = Category.query.order_by(Category.sort.asc()).all()
    return jsonify({
        'code': 0,
        'data': marshal(category, category_fields)
    }), 200


def get_secondary_category_list():
    """ 获取副分类列表 """
    category = SecondaryCategory.query.order_by(SecondaryCategory.sort.asc()).all()
    return jsonify({
        'code': 0,
        'data': marshal(category, category_fields)
    }), 200


# @auth.login_required
def get_ranking():
    """ 排行榜 type 0:娃娃榜 1:兑换榜 """
    args = rank_type_args.parse_args()
    rank_type = args.get('rank_type')
    rtype = args.get('type', 0)
    top = args.get('top', 10)

    sql = "select a.user_id as user_id, b.nickname as nickname, b.avatar as avatar," \
          " ABS(SUM(a.doll)) as doll from t_user_record a left join t_user b on a.user_id = b.id"

    if rtype:
        sql += " where a.type = 2 or a.type = 3"
    else:
        sql += " where a.type = 1"

    if rank_type:
        sql += " and DATE_FORMAT(a.created,'%Y%m') = DATE_FORMAT(CURDATE(),'%Y%m')"

    sql += " and user_id !=10011671 GROUP BY a.user_id ORDER BY doll DESC LIMIT " + str(top)

    result = db.session.execute(sql)
    rows = result.fetchall()
    return jsonify({
        'code': 0,
        'message': '成功',
        'data': marshal(rows, rank_fields)
    }), 200


@auth.login_required
def get_my_ranking():
    pass


@auth.login_required
def get_sponsor_records():
    """ 获取赞助记录 """
    args = get_param_parser.parse_args()
    user = g.user
    query = UserSponsorRecord.query.filter(or_(UserSponsorRecord.to_id == user.id, UserSponsorRecord.from_id == user.id)).order_by(UserSponsorRecord.created.asc())

    page_args = pagination_parser.parse_args(req=args)
    page = page_args.get('page')
    per_page = page_args.get('per_page')

    _sponsor_records = query.paginate(page, per_page=per_page, error_out=False)

    return jsonify({
        'code': 0,
        'data': {
            'list': marshal(_sponsor_records.items, sponsor_records_fields),
            "pageSize": _sponsor_records.per_page,
            "pageNo": _sponsor_records.page,
            "pages": _sponsor_records.pages,
            "total": _sponsor_records.total
        }
    }), 200


@auth.login_required
def get_doll_records():
    """ 获取娃娃使用记录 """
    args = get_param_parser.parse_args()
    user = g.user
    query = UserRecord.query.filter_by(user_id=user.id).order_by(UserRecord.created.desc())

    page_args = pagination_parser.parse_args(req=args)
    page = page_args.get('page')
    per_page = page_args.get('per_page')

    _records = query.paginate(page, per_page=per_page, error_out=False)

    return jsonify({
        'code': 0,
        'data': {
            'list': marshal(_records.items, doll_records_fields),
            "pageSize": _records.per_page,
            "pageNo": _records.page,
            "pages": _records.pages,
            "total": _records.total
        }
    }), 200


# @auth.login_required
def get_latest_orders():
    """  获取门店最新兑换记录 """
    args = get_param_parser.parse_args()

    query = Order.query.filter(not_(Order.order_no.like('%000000000000%'))).filter(Order.status == 3).order_by(Order.order_time.desc())

    page_args = pagination_parser.parse_args(req=args)
    page = page_args.get('page')
    per_page = page_args.get('per_page')

    _orders = query.paginate(page, per_page=per_page, error_out=False)

    return jsonify({
        'code': 0,
        'data': {
            'list': marshal(_orders.items, lastest_order_fields),
            "pageSize": _orders.per_page,
            "pageNo": _orders.page,
            "pages": _orders.pages,
            "total": _orders.total
        }
    }), 200


# @auth.login_required
def get_latest_orders_by_id(goods_id):
    """ 获取某一商品的最新兑换记录 """
    args = get_param_parser.parse_args()

    query = Order.query.filter_by(goods_id=goods_id).order_by(Order.order_time.desc())

    page_args = pagination_parser.parse_args(req=args)
    page = page_args.get('page')
    per_page = page_args.get('per_page')

    _orders = query.paginate(page, per_page=per_page, error_out=False)

    return jsonify({
        'code': 0,
        'data': {
            'list': marshal(_orders.items, lastest_order_fields),
            "pageSize": _orders.per_page,
            "pageNo": _orders.page,
            "pages": _orders.pages,
            "total": _orders.total
        }
    }), 200


@auth.login_required
def sponsor_doll():
    """ 赠送娃娃 """
    args = sponsor_args.parse_args()
    doll = args.get('doll')
    to_user = User.query.get(args.get('to_uid'))
    if not to_user:
        raise APIException(USER_NOT_EXISTS)
    from_user = g.user
    if from_user.doll < doll:
        raise APIException(DOLL_NOT_ENOUGH)
    from_user.doll -= doll
    to_user.doll += doll
    from_user.update()
    to_user.update()
    row = {
        'from_id': from_user.id,
        'from_name': from_user.nickname,
        'to_id': to_user.id,
        'to_name': to_user.nickname,
        'doll': doll
    }
    UserSponsorRecord.create(**row)
    # 插入用户娃娃变更记录
    record_row1 = {
        'user_id': from_user.id,
        'type': 4,
        'doll': -doll
    }
    UserRecord.create(**record_row1)
    record_row2 = {
        'user_id': to_user.id,
        'type': 4,
        'doll': doll
    }
    UserRecord.create(**record_row2)
    return jsonify({
        'code': 0,
        'message': '赞助成功',
        'data': {}
    }), 200


def get_remote_area():
    results = RemoteArea.query.all()
    areas = []
    for result in results:
        areas.append(result.name)
    data = ','.join(areas)

    return jsonify({
        'code': 0,
        'message': '成功',
        'data': data
    }), 200
